home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SNNSV32.ZIP / SNNSv3.2 / xgui / sources / ui_netGraph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-25  |  19.3 KB  |  665 lines

  1. /*****************************************************************************
  2.   FILE           : ui_netGraph.c
  3.   SHORTNAME      : netGraph.c
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : routines to draw all graphic elements of the net
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Tilman Sommer
  10.   DATE           : 18.5.1990
  11.  
  12.   CHANGED BY     :
  13.   IDENTIFICATION : @(#)ui_netGraph.c    1.14 3/23/94
  14.   SCCS VERSION   : 1.14
  15.   LAST CHANGE    : 3/23/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.              
  19. ******************************************************************************/
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <math.h>
  24.  
  25. #include "ui.h"
  26. #include "ui_utilP.h"
  27. #include "ui_setup.h"
  28. #include "ui_xGraphic.h"
  29. #include "ui_color.h"
  30. #include "ui_mainP.h"
  31. #include "kr_typ.h"
  32. #include "kr_const.h"
  33. #include "kr_def.h"
  34. #include "kernel.h"
  35. #include "kr_mac.h"
  36. #include "glob_typ.h"
  37.  
  38. #include "kr_ui.h"
  39.  
  40. #include "ui_display.h"
  41.  
  42. #include "ui_netGraph.ph"
  43.  
  44.  
  45. #if !defined( M_PI )
  46. #  define M_PI  3.14159265358979323846
  47. #endif
  48.  
  49.  
  50. /*****************************************************************************
  51.   FUNCTION : ui_drawGrowingThing
  52.  
  53.   PURPOSE  : draws an growing box according the procent_value (can be 
  54.              either activation or output of a unit)
  55.   RETURNS  : alteration of the graphic
  56.   NOTES    : The size of the box represents the absolut-value of the box.
  57.              The box is filled black --> positive value
  58.          The box is filled white --> negative value
  59.  
  60.   UPDATE   :
  61. *****************************************************************************/
  62.  
  63. void ui_drawGrowingThing (struct Ui_DisplayType *displayPtr, 
  64.     struct PosType gridPos, int procent_value)
  65.                  /* procent_value: [-100,+100] range */
  66. {
  67.     struct PosType   pixUpperLeftPos, pixLowerRightPos;
  68.     int              xSize, ySize;
  69.     Bool             positivValue = TRUE;
  70.     Bool             performDraw  = FALSE;
  71.     int              pVal = procent_value;
  72.     
  73.     if (displayPtr->frozen) {
  74.     positivValue = FALSE;
  75.     pVal = 100;
  76.     } else {
  77.     positivValue  = (pVal >= 0);
  78.     pVal          = abs(pVal);
  79.     }
  80.  
  81.     pixUpperLeftPos   = ui_utilGridToPix(displayPtr, gridPos);
  82.     
  83.     xSize             = (ui_unitWidth  * pVal + 50 /* round */) / 100;
  84.     ySize             = (ui_unitHeight * pVal + 50 /* round */) / 100;
  85.     
  86.     if (xSize > 0) {
  87.     pixUpperLeftPos.x  -= xSize / 2;
  88.     pixUpperLeftPos.y  -= ySize / 2;
  89.     pixLowerRightPos.x  = pixUpperLeftPos.x + xSize - 1;
  90.     pixLowerRightPos.y  = pixUpperLeftPos.y + ySize - 1;
  91.     performDraw = TRUE;
  92.     }
  93.     
  94.  /* growing bar:
  95.  
  96.     pixUpperLeftPos   = ui_utilGridToPix(displayPtr, gridPos);
  97.     pixLowerRightPos  = pixUpperLeftPos;
  98.     
  99.     xSize             = ui_unitWidth;
  100.     ySize             = ui_unitHeight * pVal / 100;
  101.     
  102.     if (ySize > 0) {
  103.     pixUpperLeftPos.x  -= xSize / 2;
  104.     pixUpperLeftPos.y  -= (ySize - (ui_unitHeight / 2));
  105.     pixLowerRightPos.x += xSize / 2;
  106.     pixLowerRightPos.y += ui_unitHeight / 2;
  107.     performDraw = TRUE;
  108.     }
  109.     
  110.  */
  111.     if (performDraw) 
  112.     if (positivValue) 
  113.         ui_xDeleteRect(ui_display, displayPtr->drawable, ui_gc,
  114.                pixUpperLeftPos, pixLowerRightPos);
  115.     else 
  116.         ui_xDrawBox(ui_display, displayPtr->drawable, ui_gc,  
  117.             pixUpperLeftPos, pixLowerRightPos);
  118.  
  119. #ifdef DEBUG
  120.     XFlush(ui_display);
  121. #endif
  122. }
  123.  
  124.  
  125. /*****************************************************************************
  126.   FUNCTION : ui_drawUnit
  127.  
  128.   PURPOSE  : draws a unit whith activation or output in different formats
  129.   RETURNS  : alteration of the graphic
  130.   NOTES    : format options are:
  131.              - UI_DRAW or UI_ERASE (operation)
  132.          - show activation or output
  133.          - show value numerically
  134.          - show unit number
  135.          - show as growing bar or growing box
  136.  
  137.   UPDATE   :
  138. *****************************************************************************/
  139.  
  140. void ui_drawUnit (struct Ui_DisplayType *displayPtr, int unitNo, 
  141.         FlagType operation)
  142.  
  143. {   
  144.     char               buf[50];
  145.     FlintType          value;
  146.     int                procent_value;
  147.     struct PosType     gridPos, pixPos;
  148.  
  149.     int                xUpperLeft, yUpperLeft;
  150.  
  151.     int                direction_hint, font_ascent, font_descent;
  152.     XCharStruct        overall;
  153.  
  154.     if (NOT ui_isUnitVisibleInDisplay(displayPtr, unitNo))
  155.       return;
  156.  
  157.     if ((displayPtr->setup).unitScaleFactor < 0.00001) 
  158.     (displayPtr->setup).unitScaleFactor = 1.0;
  159.  
  160.     switch ((displayPtr->setup).showValue) {
  161.       case UI_ACTIVATION:
  162.     value = krui_getUnitActivation(unitNo);
  163.     break;
  164.       case UI_INITIAL_ACTIVATION:
  165.     value = krui_getUnitInitialActivation(unitNo);
  166.     break;
  167.       case UI_OUTPUT: 
  168.     value = krui_getUnitOutput(unitNo);
  169.     break;
  170.       case UI_BIAS:
  171.     value = krui_getUnitBias(unitNo);
  172.         break;
  173.     }
  174.  
  175.     if (value >= 0.0) {
  176.     procent_value = 
  177.         abs((int)(100.0 * value / (displayPtr->setup).unitScaleFactor));
  178.     if (procent_value > 100) procent_value = 100;
  179.     /* triggered     = (value >= (displayPtr->setup).unitPosTrigger); */
  180.     } else {
  181.     procent_value = 
  182.         -abs((int)(100.0 * value / (displayPtr->setup).unitScaleFactor));
  183.     if (procent_value < -100) procent_value = -100;
  184.     /* triggered     = (-value >= (displayPtr->setup).unitNegTrigger); */
  185.     }
  186.     
  187.     /* if (triggered) { */
  188.     krui_getUnitPosition(unitNo, &gridPos);
  189.     gridPos.x = gridPos.x;
  190.     gridPos.y = gridPos.y;
  191.     gridPos.z = gridPos.z;
  192.     pixPos = ui_utilPixUpperLeft(displayPtr, gridPos);
  193.     xUpperLeft = pixPos.x; 
  194.     yUpperLeft = pixPos.y;
  195.     
  196.     /* set background */
  197.     XSetBackground(ui_display, ui_gc, 
  198.            ui_backgroundColor);
  199.  
  200.     if (ui_col_monochromeMode AND (operation != UI_ERASE_BOTTOM)) { 
  201.     XSetFunction(ui_display, ui_gc, GXcopy);
  202.     XSetForeground(ui_display, ui_gc, 
  203.                ui_backgroundColor);
  204.     ui_xDeleteRect(ui_display, displayPtr->drawable, ui_gc,
  205.                pixPos, ui_utilPixLowerRight(displayPtr, gridPos,0));
  206.     } 
  207.     
  208.     if (operation == UI_ERASE) {
  209.     /* XDrawImageString() don't uses the FUNCTION value in a gc.
  210.        Thus invert the colours */
  211.     XSetForeground(ui_display, ui_gc, 
  212.                ui_backgroundColor);
  213.     XSetFunction(ui_display, ui_gc, GXcopyInverted);
  214.     } else { /* DRAW */
  215.     XSetForeground(ui_display, ui_gc, ui_textColor);
  216.     XSetFunction(ui_display, ui_gc, GXcopy);
  217.     }
  218.  
  219.     if (operation != UI_ERASE_BOTTOM) {
  220.     /* print number first !! Because the space behind a character is 
  221.        some pixels deeper than the bottom line of numbers (0,1,2,3...) in
  222.        this character set. Therefore they would erase a piece of a unit
  223.        with a high value! */
  224.  
  225.     if ((displayPtr->setup).showTitleFlg) {
  226.             switch ((displayPtr->setup).showTitle) {
  227.                 case UI_NUMBER : sprintf(buf,"%d",unitNo);
  228.                                  break;
  229.             case UI_ZVALUE : sprintf(buf,"%d",gridPos.z);
  230.                                  break;
  231.             case UI_NAME   : if ((krui_getUnitName(unitNo) == NULL) OR
  232.                                    (strlen(krui_getUnitName(unitNo)) == 0))
  233.                                      sprintf(buf,"%d",unitNo);
  234.                              else
  235.                                   sprintf(buf,"%s", krui_getUnitName(unitNo));
  236.                                  break;
  237.             case UI_WINNER : if (krui_getUnitValueA(unitNo)!=0)
  238.                            sprintf(buf,"%d",(int)krui_getUnitValueA(unitNo));
  239.                          else 
  240.                                      *buf=0;
  241.                                  break;
  242.  
  243.                 default        : sprintf(buf,"%d",unitNo);
  244.             }
  245.         XDrawImageString(ui_display, displayPtr->drawable, ui_gc,
  246.                  xUpperLeft, yUpperLeft-1, buf, (int) strlen(buf));
  247. /*
  248.         if (((displayPtr->setup).showTitle == UI_NUMBER) OR 
  249.         (krui_getUnitName(unitNo) == NULL) OR
  250.         (strlen(krui_getUnitName(unitNo)) == 0)) {
  251.         sprintf(buf,"%d",unitNo);
  252.         XDrawImageString(ui_display, displayPtr->drawable, ui_gc,
  253.                  xUpperLeft, yUpperLeft-1, buf, strlen(buf));
  254.         } else {
  255.                 if ((displayPtr->setup).showTitle == UI_ZVALUE) {
  256.                     sprintf (buf, "%d", gridPos.z);
  257.                 XDrawImageString(ui_display, displayPtr->drawable, ui_gc,
  258.                      xUpperLeft, yUpperLeft-1, buf, strlen(buf));
  259.         } else {
  260.                 sprintf(buf,"%s", krui_getUnitName(unitNo));
  261.             XDrawImageString(ui_display, displayPtr->drawable, ui_gc,
  262.                          xUpperLeft, yUpperLeft-1, buf, strlen(buf));
  263.             }
  264.         }
  265. */
  266.     }
  267.     
  268. #ifdef DEBUG
  269.     XFlush(ui_display);
  270. #endif
  271.     }
  272.  
  273.     /* now the value */
  274.     
  275.     if ((displayPtr->setup).showValueFlg) {
  276.     sprintf(buf,"%4.3f", value);
  277.     XTextExtents(ui_fontStruct, buf, (int) strlen(buf),
  278.              &direction_hint, &font_ascent, &font_descent, 
  279.              &overall);
  280.     XDrawImageString(ui_display, displayPtr->drawable, ui_gc,
  281.              xUpperLeft, 
  282.              yUpperLeft + ui_unitHeight + font_ascent + 1, 
  283.              buf, (int) strlen(buf));
  284.     }
  285.     
  286. #ifdef DEBUG
  287.     XFlush(ui_display);
  288. #endif
  289.  
  290.     if (operation != UI_ERASE_BOTTOM) {
  291.  
  292.     /* now draw the unit itsself */
  293.     if (operation == UI_DRAW) {
  294.         if (NOT ui_col_monochromeMode) {
  295.         XSetForeground(ui_display, ui_gc, 
  296.                    ui_col_rangePixels[ui_col_steps + 
  297.                           procent_value * ui_col_steps 
  298.                           DIV 100]);
  299.         ui_xDeleteRect(ui_display, displayPtr->drawable, ui_gc,
  300.                    pixPos, ui_utilPixLowerRight(displayPtr, gridPos,0));        
  301.         } else { 
  302.         XSetFunction(ui_display, ui_gc, GXcopy);
  303.         XSetForeground(ui_display, ui_gc, 
  304.                    ui_textColor);
  305.         ui_drawGrowingThing(displayPtr, gridPos, procent_value);
  306.         }
  307.     } else { /* ERASE */
  308.         if (NOT ui_col_monochromeMode) {
  309.         XSetFunction(ui_display, ui_gc, GXcopy);
  310.         XSetForeground(ui_display, ui_gc, 
  311.                    ui_backgroundColor);
  312.         ui_xDeleteRect(ui_display, displayPtr->drawable, ui_gc,
  313.                    pixPos, ui_utilPixLowerRight(displayPtr, gridPos,0));
  314.         }
  315.     }
  316.     /* if operation == UI_ERASE: there is nothing to draw. area is 
  317.        already erased by ui_xDeleteRect() */
  318.     
  319. #ifdef DEBUG
  320.     XFlush(ui_display);
  321. #endif
  322.     }
  323. }
  324.  
  325.  
  326. /*****************************************************************************
  327.   FUNCTION : ui_arrowPoint
  328.  
  329.   PURPOSE  : calculates the start-/end-point of a Link
  330.   RETURNS  : the calculated position
  331.   NOTES    : call this routine with exchanged source- and target positions
  332.              to calculate the end-point
  333.          !!! The algorithm used allows only quadratic units i.e. 
  334.              ui_unitHeight == ui_unitWidth !!!
  335.  
  336.   UPDATE   :
  337. *****************************************************************************/
  338.  
  339. static struct PosType ui_arrowPoint (struct PosType sourcePixPos, 
  340.             struct PosType targetPixPos)
  341.  
  342. {
  343.     struct PosType  arrowPoint;
  344.     int               deltaX, deltaY;
  345.     int               halfSize = ui_unitWidth / 2 + 1;
  346.                       /* keep a distance from 1 round a 100% unit */
  347.  
  348.     deltaX   = targetPixPos.x - sourcePixPos.x;
  349.     deltaY   = targetPixPos.y - sourcePixPos.y;
  350.     
  351.     if (abs(deltaX) >= abs(deltaY)) {
  352.     deltaY = deltaY * halfSize / abs(deltaX);
  353.     if (deltaX >= 0) deltaX = halfSize;
  354.     else deltaX = - halfSize;
  355.     } else {
  356.     deltaX = deltaX * halfSize / abs(deltaY);
  357.     if (deltaY >= 0) deltaY = ui_utilSgnInt(deltaY) * halfSize;
  358.     else deltaY = - halfSize;
  359.     }
  360.     
  361.     arrowPoint.x = sourcePixPos.x + deltaX;
  362.     arrowPoint.y = sourcePixPos.y + deltaY;
  363.  
  364.     return(arrowPoint);
  365. }
  366.  
  367.  
  368. /*****************************************************************************
  369.   FUNCTION : ui_areConnected 
  370.  
  371.   PURPOSE  : returns true, if there exists a link from unit sourceNo to
  372.              targetNo 
  373.   NOTES    : 
  374.  
  375.   UPDATE   :
  376. *****************************************************************************/
  377.  
  378. Bool ui_areConnected (int sourceNo, int targetNo)
  379. {
  380.   struct Link *link_ptr ;
  381.   struct Unit *s_unit_ptr, *t_unit_ptr ;
  382.   struct Site *site_ptr ;
  383.  
  384.  
  385.   s_unit_ptr = kr_getUnitPtr (sourceNo) ;
  386.   t_unit_ptr = kr_getUnitPtr (targetNo) ;
  387.  
  388.   if UNIT_HAS_DIRECT_INPUTS (t_unit_ptr)
  389.     for (link_ptr = (struct Link *) t_unit_ptr->sites ;
  390.          link_ptr != NULL ;
  391.          link_ptr = link_ptr->next)
  392.       if (link_ptr->to == s_unit_ptr) return (True) ;
  393.   else
  394.     if UNIT_HAS_SITES (t_unit_ptr)
  395.       for (site_ptr = t_unit_ptr->sites ;
  396.            site_ptr != NULL ;
  397.            site_ptr = site_ptr->next)
  398.         for (link_ptr = site_ptr->links ;
  399.              link_ptr != NULL ;
  400.              link_ptr = link_ptr->next)
  401.           if (link_ptr->to == s_unit_ptr) return (True) ;
  402.  
  403.   return (False) ;
  404. }
  405.  
  406.  
  407.  
  408. /*****************************************************************************
  409.   FUNCTION : ui_angle
  410.  
  411.   PURPOSE  : returns the angle between the line from source to target and a
  412.              horizontal line from source 
  413.   NOTES    : 
  414.  
  415.   UPDATE   :
  416. *****************************************************************************/
  417.  
  418. static double ui_angle (struct PosType source, struct PosType target)
  419.  
  420. {
  421.   double dx, dy, l, angle ;
  422.  
  423.  
  424.   dx = target.x - source.x ;
  425.   dy = target.y - source.y ;
  426.         
  427.   l = sqrt (dx * dx + dy * dy) ;
  428.     
  429.   angle = asin (fabs(dy) / l) * 180.0 / M_PI ;
  430.  
  431.   if (dx >= 0)
  432.   {
  433.     if (dy >= 0) angle = 360.0 - angle ; 
  434.   }
  435.   else
  436.   {
  437.     if (dy >= 0) angle = 180.0 + angle ;
  438.     else         angle = 180.0 - angle ;
  439.   }
  440.  
  441.   return (angle) ;
  442. }
  443.  
  444.  
  445.  
  446. /*****************************************************************************
  447.   FUNCTION : ui_drawLink
  448.  
  449.   PURPOSE  : draws an arrow (or line) from unitPos to targetPos
  450.   RETURNS  : alteration of the network
  451.   NOTES    : The routine checks first
  452.                - have the units the same subNetNo
  453.            - are both units visible (layers on and visible in a window)
  454.              the format can be:
  455.              - as line or as arrow (i.e. with direction indicator)
  456.          - with or without weight in numerical form
  457.  
  458.   UPDATE   :
  459. *****************************************************************************/
  460.  
  461. void ui_drawLink (struct Ui_DisplayType *displayPtr, int sourceNo, 
  462.             int targetNo, FlintType weight, FlagType operation)
  463.                       /*  operation:  UI_DRAW or UI_ERASE */
  464. {
  465.     struct PosType   sourcePixPos, targetPixPos, textPixPos;
  466.     struct PosType   sourceGridPos, targetGridPos;
  467.     struct PosType   arrowStart, arrowEnd;
  468.     char             buf[10];
  469.     Bool             triggered;
  470.     int              procent_value;
  471.     FlintType        quotient;
  472.     struct           PosType arc, delta ;
  473.     int              arc_r, arc_dist = 20 ;
  474.     double           angle1, angle2 ;
  475.     double           len ;
  476.  
  477.     if (NOT (displayPtr->setup).showLinkFlg)
  478.     return;
  479.     
  480.     if (krui_getUnitSubnetNo(sourceNo) != krui_getUnitSubnetNo(targetNo))
  481.     return;
  482.  
  483.     /* same subnet ... */
  484.     
  485.     if (NOT (ui_isUnitVisibleInDisplay(displayPtr, sourceNo) AND
  486.          ui_isUnitVisibleInDisplay(displayPtr, targetNo)))
  487.     /* one or both units are not visible */
  488.       return;
  489.     
  490.     /* one visible layer containing both units was found */
  491.    
  492.     if (weight >= 0.0) 
  493.     triggered = (weight >= (displayPtr->setup).linkPosTrigger);
  494.     else
  495.     triggered = (weight <= (displayPtr->setup).linkNegTrigger);
  496.  
  497.     if (NOT triggered) return;
  498.  
  499.     krui_getUnitPosition(sourceNo, &sourceGridPos);
  500.     krui_getUnitPosition(targetNo, &targetGridPos);
  501.  
  502.     if ((ui_utilAreEqualPositions(sourceGridPos, targetGridPos)) &&
  503.         (sourceNo != targetNo))
  504.  
  505.         return;
  506.  
  507.     /****************************************************/
  508.     /* Now everything is checked, get data and draw ... */
  509.  
  510.     sourcePixPos = ui_utilGridToPix(displayPtr, sourceGridPos);
  511.     targetPixPos = ui_utilGridToPix(displayPtr, targetGridPos);
  512.  
  513.     textPixPos.x  = (targetPixPos.x + sourcePixPos.x)/2 - 10;
  514.     textPixPos.y  = (targetPixPos.y + sourcePixPos.y)/2 +  3;
  515.     
  516.     XSetFunction(ui_display, ui_gc, GXcopy);
  517.      /* set background */
  518.     XSetBackground(ui_display, ui_gc, 
  519.            ui_backgroundColor);
  520.  
  521.     if (operation == UI_DRAW) {
  522.     if (NOT ui_col_monochromeMode) {
  523.         if (weight >= 0.0) {
  524.           if ((displayPtr->setup).linkScaleFactor != 0.0)
  525.           {
  526.         quotient = fabs(weight / (displayPtr->setup).linkScaleFactor);
  527.         if (quotient < 1.0)
  528.             procent_value = (int)(100.0 * quotient);
  529.         else
  530.             procent_value = 100;
  531.           }
  532.           else
  533.           procent_value = 100;
  534.           XSetForeground(ui_display, ui_gc, 
  535.                    ui_col_rangePixels[ui_col_steps + 
  536.                           procent_value * ui_col_steps 
  537.                           DIV 100]);
  538.         } else {
  539.           if ((displayPtr->setup).linkScaleFactor != 0.0)
  540.           {
  541.         quotient = fabs(weight / (displayPtr->setup).linkScaleFactor);
  542.         if (quotient < 1.0)
  543.             procent_value = (int)(100.0 * quotient);
  544.         else
  545.             procent_value = 100;
  546.           }
  547.           else
  548.           procent_value = 100;
  549.           XSetForeground(ui_display, ui_gc, 
  550.                    ui_col_rangePixels[ui_col_steps - 
  551.                           procent_value * ui_col_steps 
  552.                           DIV 100]);
  553.         }        
  554.     } else
  555.         XSetForeground(ui_display, ui_gc, 
  556.                ui_textColor);
  557.     } else { /* ERASE */
  558.     XSetForeground(ui_display, ui_gc, 
  559.                ui_backgroundColor);
  560.     }
  561.     
  562.     if (sourceNo != targetNo)
  563.     {  
  564.       arrowStart = ui_arrowPoint (sourcePixPos, targetPixPos ) ;
  565.       arrowEnd   = ui_arrowPoint (targetPixPos, sourcePixPos ) ;
  566.  
  567.       if (ui_areConnected (targetNo, sourceNo)) 
  568.       {
  569.         /* draw link as an arc */
  570.  
  571.         delta.x = arrowEnd.x - arrowStart.x ;
  572.         delta.y = arrowEnd.y - arrowStart.y ;
  573.  
  574.         len   = sqrt ((double) (delta.x * delta.x + delta.y * delta.y)) ;
  575.         arc_r = ((delta.x * delta.x + delta.y * delta.y)  
  576.                  + 4 * arc_dist * arc_dist) / (8 * arc_dist) ; 
  577.  
  578.         if (len < 4.0 * arc_dist) arc_dist = len / 4 ;
  579.  
  580.         arc.x = arrowStart.x + delta.x/2 - (arc_r - arc_dist) * delta.y/len ;
  581.         arc.y = arrowStart.y + delta.y/2 + (arc_r - arc_dist) * delta.x/len ;
  582.  
  583.         textPixPos.x = arrowStart.x + delta.x/2 + arc_dist * delta.y/len -17 ;
  584.         textPixPos.y = arrowStart.y + delta.y/2 - arc_dist * delta.x/len + 5 ;
  585.  
  586.         angle1 = ui_angle (arc, arrowStart) ;
  587.         angle2 = ui_angle (arc, arrowEnd  ) ;
  588.         if (angle1 < angle2) angle1 += 360.0 ;
  589.  
  590.         XDrawArc (ui_display, displayPtr->drawable, ui_gc, 
  591.                   arc.x - arc_r, arc.y - arc_r, 2 * arc_r, 2 * arc_r, 
  592.                   (int) (angle2 * 64.0),
  593.                   (int) ((angle1  - angle2) * 64.0)) ;
  594.  
  595.         arrowStart.x = arrowEnd.x + (arrowEnd.y - arc.y) ;
  596.         arrowStart.y = arrowEnd.y - (arrowEnd.x - arc.x) ;
  597.  
  598.       }
  599.       else
  600.       {
  601.         /* draw link as a line */
  602.  
  603.         ui_xDrawLine(ui_display, displayPtr->drawable, ui_gc, 
  604.                      arrowStart, arrowEnd) ;
  605.       }
  606.     }
  607.     else
  608.     {
  609.       /* self recurrent link */
  610.  
  611.       XDrawArc (ui_display, displayPtr->drawable, ui_gc,
  612.                 sourcePixPos.x - ui_unitWidth, sourcePixPos.y,
  613.                 ui_unitWidth, ui_unitHeight,
  614.                 90 * 64, 270*64) ;
  615.  
  616.       textPixPos.x = sourcePixPos.x - ui_unitWidth    - 32 ;
  617.       textPixPos.y = sourcePixPos.y + ui_unitHeight/2 +  2 ;
  618.  
  619.       arrowStart.x = sourcePixPos.x - ui_unitWidth/2 - 4 ;
  620.       arrowStart.y = sourcePixPos.y + 1 ;
  621.  
  622.       arrowEnd.x   = arrowStart.x + 3 ;
  623.       arrowEnd.y   = arrowStart.y     ;
  624.     }
  625.  
  626. #ifdef DEBUG
  627.    XFlush(ui_display);
  628. #endif
  629.  
  630.     if ((displayPtr->setup).showDirectionFlg) {
  631.     ui_xDrawTriangle(ui_display, displayPtr->drawable, ui_gc, 
  632.              arrowStart, arrowEnd);
  633. #ifdef DEBUG
  634.     XFlush(ui_display);
  635. #endif
  636.     }
  637.  
  638.     if ((displayPtr->setup).showWeightFlg) {
  639.     /* Show Link weight if toggle set by the user */ 
  640.     if (operation == UI_DRAW)
  641.         XSetForeground(ui_display, ui_gc, 
  642.                ui_textColor);
  643.     sprintf(buf,"%5.3f",weight);
  644.     /* if (operation == UI_DRAW)  */
  645.         XDrawImageString(ui_display, displayPtr->drawable, ui_gc, 
  646.                  textPixPos.x, textPixPos.y, buf, (int) strlen(buf));
  647.     /* else
  648.         XDrawString(ui_display, displayPtr->drawable, ui_gc, 
  649.             textPixPos.x, textPixPos.y, buf, strlen(buf)); */
  650.     }
  651. #ifdef DEBUG
  652.     XFlush(ui_display);
  653. #endif
  654.  
  655. }
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663. /* end of file */
  664. /* lines: 518 */
  665.